/* Copyright 2007 Gearbox Software - http://www.gearboxsoft.com
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 
     http:www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.*/


namespace GearBlog.Web.Controllers
{
	using System;
	using System.Collections;
	using System.Collections.Specialized;
	using System.Globalization;
	using Castle.ActiveRecord;
	using Castle.MonoRail.Framework;
	using GearBlog.Web.Filters;
	using GearBlog.Web.Models;
	using GearBlog.Web.Utils;
	using NHibernate;

	[Layout("default")]
	[BlogAccessFilter(BlogAccessType.Reader, typeof(FormsAuthenticationAgent))]
	[AuthenticationFilter(typeof(FormsAuthenticationAgent),RequiresLogin = false)]
    public class BlogController : ExtendedControllerBase
    {
    
        public void Index()
        {
        	PropertyBag["Posts"] = Post.FindAllAfter(DateTime.Now.AddDays(-Setting.NumOfDaysBeforeArchive));


        }
        
        public void ShowPost(int id)
        {
            PropertyBag["Post"] = Post.Find(id);

        }
		public void SubscribeComments(int id)
		{
			Post post = Post.Find(id);
			if (!post.CommentSubscribers.Contains(CurrentUser))
				post.CommentSubscribers.Add(CurrentUser);
		}
		public void UnsubscribeComments(int id)
		{
			Post post = Post.Find(id);
			if (post.CommentSubscribers.Contains(CurrentUser))
				post.CommentSubscribers.Remove(CurrentUser);
		}
		
        
        public void ShowArchives()
        {
        	ArrayList result = (ArrayList) ActiveRecordMediator.ExecuteQuery(new PostRangeQuery());
			if (((object[])result[0])[0] != null)
			{
				DateTime minDate = (DateTime) ((object[]) result[0])[0];
				DateTime maxDate = (DateTime) ((object[]) result[0])[1];
				DateTime iterateDate = minDate;

				YearSlotCollection yearSlots = new YearSlotCollection();


				while (iterateDate.Month < maxDate.Month || iterateDate.Year < maxDate.Year)
				{
					AddSlot(yearSlots, iterateDate);
					iterateDate = iterateDate.AddMonths(1);
				}

				// Add the last one which is the max year
				AddSlot(yearSlots, maxDate);


				PropertyBag["YearSlots"] = yearSlots;
			}
        }
		public void ShowMonthPost(int year, int month)
		{
			Flash["Posts"] = Post.FindAllByYearMonth(year, month);
			if (!RequestUtil.IsAjax(Request)) RedirectToAction("showarchives");
		}
		private static void AddSlot(YearSlotCollection yearSlots, DateTime iterateDate)
		{
			YearSlot currentYear;
			if (yearSlots.Contains(iterateDate.Year))
				currentYear = yearSlots[iterateDate.Year];
			else
			{
				currentYear = new YearSlot(iterateDate.Year);
				yearSlots.Add(currentYear);
			}
			currentYear.MonthSlots.Add(new MonthSlot(iterateDate.Month));
			
		}
        public void ShowTagPost(int tagID)
        {
            Tag tag = Tag.Find(tagID);
            PropertyBag["Tag"] = tag;
        }

    }

	
	public class MonthSlot
	{
		private int _month;

		public MonthSlot(int month)
		{
			_month = month;
		}

		public int Month
		{
			get { return _month; }
			set { _month = value; }
		}

		public string GetMonthName()
		{
			return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(_month);
		}
	}

	public class MonthSlotCollection:IEnumerable
	{
		private OrderedDictionary _dictionary=new OrderedDictionary();
		public void Add(MonthSlot monthSlot)
		{
			_dictionary.Add(monthSlot.Month,monthSlot);

		}
		public void Remove(int month)
		{
			_dictionary.Remove(month);
		}
		public MonthSlot this[int month]
		{
			get { return (MonthSlot)_dictionary[month]; }
		}
		public IEnumerator GetEnumerator()
		{
			return _dictionary.Values.GetEnumerator();
		}
	}
	public class YearSlot
	{
		private int _year;
		private MonthSlotCollection _monthSlots=new MonthSlotCollection();

		public YearSlot(int year)
		{
			_year = year;
		}

		public int Year
		{
			get { return _year; }
			set { _year = value; }
		}


		public MonthSlotCollection MonthSlots
		{
			get { return _monthSlots; }
			set { _monthSlots = value; }
		}
	}
	public class YearSlotCollection : IEnumerable
	{
		private OrderedDictionary _dictionary=new OrderedDictionary();

		
		public void Add(YearSlot yearSlot)
		{
			_dictionary.Add(yearSlot.Year, yearSlot);
		}
		public void Remove(int year)
		{
			_dictionary.Remove(year);
		}
		public YearSlot this[int year]
		{
			get { return (YearSlot)_dictionary[(object) year]; }
		}



		#region IEnumerable Members

		public IEnumerator GetEnumerator()
		{
			return _dictionary.Values.GetEnumerator();
		}

		#endregion

		public bool Contains(int year)
		{
			return _dictionary.Contains(year);
		}
	}


	public class PostRangeQuery : ActiveRecordBaseQuery
	{
		public PostRangeQuery()
			: base(typeof(Post))
		{
		}
		protected override IQuery CreateQuery(ISession session)
		{
			return session.CreateQuery("select min(post.CreatedAt) , max(post.CreatedAt) from Post post");

		}

	}
}
